﻿using System;

namespace Nexia.FluentHtmlElements.Utilities
{
	public class StringTrimmer : IStringTrimmer
	{
		/// <summary>
		/// This method will cut off the given input string at the first space in the characters between cutoff and cutoff + fudgeFactor.
		/// If no space is found, then the string is timmed to the cutOff length.
		/// </summary>
		/// <param name="input">The input string to trim</param>
		/// <param name="cutOff">The cut off length</param>
		/// <param name="fudgeFactor">The cut off length fudge factor</param>
		/// <returns></returns>
		public virtual string WordAwareTrim(string input, int cutOff, int fudgeFactor)
		{
			if (string.IsNullOrEmpty(input))
				return String.Empty;

			if (cutOff < 1)
				throw new ArgumentOutOfRangeException("cutOff", "Must be greater than 1");
			if (cutOff > input.Length)
				throw new ArgumentOutOfRangeException("cutOff", "Must be less than input.Length");
			if(fudgeFactor < 0)
				throw new ArgumentOutOfRangeException("fudgeFactor", "Must be greater than 0");

			if (input.Length <= cutOff)
				return input;

			var indexNextSpace = IndexOfSpace(input, cutOff, fudgeFactor);

			// If no string found, just end string at cutOff
			return indexNextSpace == -1 ? input.Substring(0, cutOff) : input.Substring(0, indexNextSpace);
		}

		/// <summary>
		/// Start at startIndex and proceed till startIndex + count (or end of string) returning the index of the first space character encountered.
		/// </summary>
		/// <remarks>Unlike String.IndexOf this method does not throw when count exceeds the bounds of the string.</remarks>
		/// <param name="input">The input string</param>
		/// <param name="startIndex">The index to start looking for a space</param>
		/// <param name="count">The max number of characters to examine (starting at startIndex)</param>
		/// <returns></returns>
		public virtual int IndexOfSpace(string input, int startIndex, int count)
		{
			if (string.IsNullOrEmpty(input))
				return -1;

			if (startIndex < 0)
				throw new ArgumentOutOfRangeException("startIndex", "Must be greater than 0");
			if(startIndex > input.Length)
				throw new ArgumentOutOfRangeException("startIndex", "Must be less than input.Length");
			if (count < 0)
				throw new ArgumentOutOfRangeException("count", "Must be greater than 0");

			//return startIndex + count < input.Length ? input.IndexOf(' ', startIndex) : input.IndexOf(' ', startIndex, count);
			return startIndex + count < input.Length ? input.IndexOf(' ', startIndex, count) : input.IndexOf(' ', startIndex);
		}
	}
}
